﻿using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;

using CommunityServer.ControlPanel.Controls;

using Telligent.Glow;

using DropDownList=Telligent.Glow.DropDownList;


namespace CSLive.ControlPanel
{
    /// <summary>
    /// The CSLive.aspx page's Code Behind
    /// </summary>
    public class ControlPanel : Page
    {
        protected ResourceLinkButton EditorButton = new ResourceLinkButton();
        protected ResourceButton InstallButton = new ResourceButton();
        protected TabbedPanes optionPanes = new TabbedPanes();
        protected PlaceHolder post1 = new PlaceHolder();
        protected PlaceHolder pre1 = new PlaceHolder();
        protected PlaceHolder pre2 = new PlaceHolder();
        protected PlaceHolder pre3 = new PlaceHolder();
        protected ResourceButton RefreshButton = new ResourceButton();
        protected ResourceButton SaveButton = new ResourceButton();
        protected StatusMessage Status = new StatusMessage();

        protected void Page_Load( object sender, EventArgs e )
        {
            InstallButton.Click += InstallButton_Click;
            RefreshButton.Click += RefreshButton_Click;
            SaveButton.Click += SaveButton_Click;
            var doc = new XmlDocument();
            doc.Load( Server.MapPath( "~/web.config" ) );
            XmlNode node = doc.SelectSingleNode( "/configuration/system.web/pages/controls/add[@tagPrefix='CSLive']" );
            if ( !Page.IsPostBack )
            {
                if ( node != null )
                {
                    pre1.Visible = false;
                    pre2.Visible = false;
                    pre3.Visible = false;
                    post1.Visible = true;
                    LoadControls();
                }
            }
            //if (node != null)
        }

        private void LoadControls()
        {
            foreach ( string s in LiveConfiguration.Instance.ControlGroups.Keys )
            {
                var tp = new TabbedPane {Tab = new TabbedPaneTab( s )};
                LiveConfiguration config = LiveConfiguration.Instance;
                foreach ( ICSLiveControl c in config.ControlGroups[ s ] )
                {
                    ConfigSetting[] settings = config.getConfigSettings( c.Name );
                    if ( settings.Length > 0 )
                    {
                        var sb = new StringBuilder();
                        sb.AppendLine( "	        <table width=\"100%\">" );
                        sb.AppendLine( "                <tr>" );
                        sb.AppendLine( "                    <td colspan=\"2\">" );
                        sb.AppendLine( "                        <div class=\"CommonFormSubTitle\">" );
                        sb.AppendLine( "                            Configure <a href=\"" + c.DocsUri +
                                       "\" target=\"_blank\">" + c.Name + "</a>" );
                        sb.AppendLine( "                        </div>" );
                        sb.AppendLine( "                    </td>" );
                        sb.AppendLine( "                </tr>" );
                        tp.Content.Controls.Add( new LiteralControl( sb.ToString() ) );
                        foreach ( ConfigSetting setting in settings )
                        {
                            if ( setting.Value.GetType() == typeof ( Html ) )
                            {
                                sb = new StringBuilder();
                                sb.AppendLine( "    	        <tr>" );
                                sb.AppendLine( "		            <td colspan=\"2\">" );
                                sb.AppendLine( "                     <div class=\"CommonFormFieldName\">" );
                                sb.AppendLine( "		                    <strong>" + setting.Name + "</strong>" );
                                sb.AppendLine( "                     </div>" );
                                sb.AppendLine( "                     <div class=\"CommonFormFieldName\">" + Regex.Replace( setting.Description, @"(\bhttp://[^ ]+\b)", @"<a href=""$0"" target=""_blank"">$0</a>" ) + "</div>" );
                                sb.AppendLine( "		                <div class=\"CommonFormField\">" );
                                tp.Content.Controls.Add( new LiteralControl( sb.ToString() ) );
                                var ed = new CommunityServer.Controls.Editor
                                             {
                                                 Height = new Unit( 150, UnitType.Pixel ),
                                                 Text = setting.Value.ToString(),
                                                 ID = ( c.Name + "$" + setting.Name ).Replace( " ", "_" )
                                             };
                                tp.Content.Controls.Add( ed );
                                sb = new StringBuilder();
                                sb.AppendLine( "		                </div>" );
                                sb.AppendLine( "		            </td>" );
                                sb.AppendLine( "	            </tr>" );
                                tp.Content.Controls.Add( new LiteralControl( sb.ToString() ) );
                            }
                            else
                            {
                                sb = new StringBuilder();
                                sb.AppendLine( "    	        <tr>" );
                                sb.AppendLine( "		            <td class=\"CommonFormFieldName\" style=\"width:350px;\">" );
                                sb.AppendLine( "		                <strong>" + setting.Name + "</strong>" );
                                sb.AppendLine( "                     <div>" + Regex.Replace( setting.Description, @"(\bhttp://[^ ]+\b)", @"<a href=""$0"" target=""_blank"">$0</a>" ) + "</div>" );
                                sb.AppendLine( "		            </td>" );
                                sb.AppendLine( "		            <td class=\"CommonFormField\">" );
                                tp.Content.Controls.Add( new LiteralControl( sb.ToString() ) );
                                if ( setting.Value.GetType() == typeof ( bool ) )
                                {
                                    var yn = new YesNoRadioButtonList
                                                 {
                                                     ID = ( c.Name + "$" + setting.Name ).Replace( ' ', '_' ),
                                                     RepeatColumns = 2,
                                                     SelectedValue = ( ( bool ) setting.Value )
                                                 };
                                    tp.Content.Controls.Add( yn );
                                }
                                else if ( setting.Value.GetType() == typeof ( DateTime ) )
                                {
                                    var dts = new DateTimeSelector
                                                  {
                                                      ID = ( c.Name + "$" + setting.Name ).Replace( ' ', '_' ),
                                                      AllowBlankValues = false,
                                                      DateTimeFormat = "d MMMM yyyy hh:mm tt",
                                                      ShowCalendarPopup = true,
                                                      DateTime = ( ( DateTime ) setting.Value )
                                                  };
                                    tp.Content.Controls.Add( dts );
                                }
                                else if ( setting.Value.GetType().IsEnum )
                                {
                                    var ddl = new DropDownList
                                                  {
                                                      ID = ( c.Name + "$" + setting.Name ).Replace( ' ', '_' ),
                                                      ShowHtmlWhenSelected = false
                                                  };
                                    foreach ( string st in Enum.GetNames( setting.Value.GetType() ) )
                                        if ( st != "value__" )
                                            ddl.Items.Add( new DropDownListItem( st ) );
                                    if ( ddl.Items.Count < 6 ) ddl.SelectListHeight = 110;
                                    ddl.SelectedValue = setting.Value.ToString();
                                    tp.Content.Controls.Add( ddl );
                                }
                                else
                                {
                                    var tb = new TextBox {ID = ( c.Name + "$" + setting.Name ).Replace( ' ', '_' )};
                                    if ( setting.Value.GetType() == typeof ( Int32 ) )
                                    {
                                        tb.MaxLength = 128;
                                        tb.Width = new Unit( 160, UnitType.Pixel );
                                    }
                                    tb.CssClass = "ControlPanelTextInput";
                                    tb.Text = setting.Value.ToString();
                                    tp.Content.Controls.Add( tb );
                                }

                                sb = new StringBuilder();
                                sb.AppendLine( "		            </td>" );
                                sb.AppendLine( "	            </tr>" );
                                tp.Content.Controls.Add( new LiteralControl( sb.ToString() ) );
                            }
                        }
                        sb = new StringBuilder();
                        sb.AppendLine( "	        </table>" );
                        tp.Content.Controls.Add( new LiteralControl( sb.ToString() ) );
                    }
                }
                optionPanes.Panes.Add( tp );
            }
        }

        private void SaveButton_Click( object sender, EventArgs e )
        {
            Status.Visible = true;
            var sb = new StringBuilder();
            var sw = new StringWriter( sb );
            Debug.Listeners.Add( new TextWriterTraceListener( sw ) );
            Debug.AutoFlush = false;

            LiveConfiguration config = LiveConfiguration.Instance;

            string startswith = optionPanes.ClientID.Replace( '_', '$' ).Remove( optionPanes.ClientID.LastIndexOf( '_' ) );
            foreach ( string s in Request.Params.AllKeys )
                if ( s.StartsWith( startswith ) && !string.Equals( optionPanes.ClientID.Replace( '_', '$' ), s ) &&
                     !string.Equals( SaveButton.ClientID.Replace( '_', '$' ), s ) )
                {
                    string[] s1 = s.Remove( 0, startswith.Length + 1 ).Replace( '_', ' ' ).Split( new[] {'$'} );
                    object o = config.getConfigSetting( s1[ 0 ], s1[ 1 ] ).Value;
                    if ( o.GetType() == typeof ( Html ) )
                    {
                        config.saveConfigSetting( s1[ 0 ], s1[ 1 ], new Html( Request.Params[ s ] ) );
                        Debug.WriteLine( "Saved " + s1[ 0 ] + "." + s1[ 1 ] + " as " + o.GetType() + "<br />" );
                    }
                    else if ( o.GetType() == typeof ( int ) )
                    {
                        config.saveConfigSetting( s1[ 0 ], s1[ 1 ], int.Parse( Request.Params[ s ] ) );
                        Debug.WriteLine( "Saved " + s1[ 0 ] + "." + s1[ 1 ] + " as an " + o.GetType() + "<br />" );
                    }
                    else if ( o.GetType() == typeof ( bool ) )
                    {
                        config.saveConfigSetting( s1[ 0 ], s1[ 1 ], bool.Parse( Request.Params[ s ] ) );
                        Debug.WriteLine( "Saved " + s1[ 0 ] + "." + s1[ 1 ] + " as a " + o.GetType() + "<br />" );
                    }
                    else if ( o.GetType() == typeof ( DateTime ) )
                    {
                        config.saveConfigSetting( s1[ 0 ], s1[ 1 ], DateTime.Parse( Request.Params[ s ] ) );
                        Debug.WriteLine( "Saved " + s1[ 0 ] + "." + s1[ 1 ] + " as " + o.GetType() + "<br />" );
                    }
                    else if ( o.GetType() == typeof ( string ) )
                    {
                        config.saveConfigSetting( s1[ 0 ], s1[ 1 ], Request.Params[ s ] );
                        Debug.WriteLine( "Saved " + s1[ 0 ] + "." + s1[ 1 ] + " as a " + o.GetType() + "<br />" );
                    }
                    else if ( o.GetType().IsEnum )
                    {
                        config.saveConfigSetting( s1[ 0 ], s1[ 1 ], Enum.Parse( o.GetType(), Request.Params[ s ] ) );
                        Debug.WriteLine( "Saved " + s1[ 0 ] + "." + s1[ 1 ] + " as a " + o.GetType() + " (Enum)<br />" );
                    }
                    else
                    {
                        Debug.WriteLine( "Unknown Data Type, unable to save <br />" );
                    }
                    //save the setting s1[1] from control s1[0]
                }
            Debug.Close();
            Status.Text = "<h2 style=\"margin: 0;\">Saved</h2>";
            Status.Text += sb.ToString();
            LoadControls();
        }

        private void RefreshButton_Click( object sender, EventArgs e )
        {
            var doc = new XmlDocument();
            doc.Load( Server.MapPath( "~/web.config" ) );
            XmlNode node = doc.SelectSingleNode( "/configuration/system.web/pages/controls/add[@tagPrefix='CSLive']" );
            if ( node != null )
            {
                pre1.Visible = false;
                pre2.Visible = false;
                pre3.Visible = false;
                post1.Visible = true;
                Status.Text =
                    "You have successfully Manually Installed <a href=\"http://www.codeplex.com/CSLive\" target=\"_blank\">CSLive</a> into the web.config file";
                Status.Visible = true;
                Status.Success = true;
                LoadControls();
            }
        }

        private void InstallButton_Click( object sender, EventArgs e )
        {
            var doc = new XmlDocument();
            doc.Load( Server.MapPath( "~/web.config" ) );
            XmlNode node = doc.SelectSingleNode( "/configuration/system.web/pages/controls" );
            XmlElement el = doc.CreateElement( "add" );
            el.SetAttribute( "tagPrefix", "CSLive" );
            el.SetAttribute( "namespace", "CSLive.Controls" );
            el.SetAttribute( "assembly", "CSLive" );
            node.AppendChild( el );
            node = doc.SelectSingleNode( "/configuration/system.web/httpHandlers" );
            XmlElement el2 = doc.CreateElement( "add" );
            el2.SetAttribute( "verb", "GET" );
            el2.SetAttribute( "path", "CSLiveResource.axd" );
            el2.SetAttribute( "validate", "false" );
            el2.SetAttribute( "type", "CSLive.Resources.ResourceHandler, CSLive" );
            node.AppendChild( el2 );
            XmlElement el3 = doc.CreateElement( "add" );
            el3.SetAttribute( "verb", "GET" );
            el3.SetAttribute( "path", "CSLiveResource.axd" );
            el3.SetAttribute( "name", "csliveresources" );
            el3.SetAttribute( "type", "CSLive.Resources.ResourceHandler, CSLive" );
            node = doc.SelectSingleNode( "/configuration/system.webServer/handlers" );
            node.AppendChild( el3 );
            try
            {
                var writer = new XmlTextWriter( Server.MapPath( "~/Web.config" ), null ) {Formatting = Formatting.Indented};
                doc.WriteTo( writer );
                writer.Flush();
                writer.Close();
                pre1.Visible = false;
                pre2.Visible = false;
                pre3.Visible = false;
                post1.Visible = true;
                Status.Text =
                    "You have successfully Automatically Installed <a href=\"http://www.codeplex.com/CSLive\" target=\"_blank\">CSLive</a> into the web.config file";
                Status.Visible = true;
                Status.Success = true;
                LoadControls();
            }
            catch
            {
                Status.Text =
                    "Current Permissions do not allow editing of the web.config file directly, you will have to manually install the CSLive control addition to the web.config file";
                Status.Visible = true;
                Status.Success = false;
                pre2.Visible = false;
            }
        }
    }
}